/**
 * 表示边界的接口
 */
export interface Bounds {
  top: number
  bottom: number
  left: number
  right: number
}

/**
 * 滚动句柄类，用于管理元素的滚动状态
 */
export class ScrollHandle {
  private offsetX: number = 0
  private offsetY: number = 0
  private maxOffsetX: number = 0
  private maxOffsetY: number = 0
  private childBounds: Bounds[] = []
  private bounds: Bounds = {
    top: 0,
    bottom: 0,
    left: 0,
    right: 0
  }

  /**
   * 构造一个新的滚动句柄
   */
  constructor() {
    // 初始化状态
  }

  /**
   * 获取当前的滚动偏移量
   */
  get offset(): { x: number; y: number } {
    return { x: this.offsetX, y: this.offsetY }
  }

  /**
   * 设置当前的滚动偏移量
   */
  set offset(value: { x: number; y: number }) {
    this.offsetX = value.x
    this.offsetY = value.y
  }

  /**
   * 获取最大滚动偏移量
   */
  get maxOffset(): { x: number; y: number } {
    return { x: this.maxOffsetX, y: this.maxOffsetY }
  }

  /**
   * 设置最大滚动偏移量
   */
  set maxOffset(value: { x: number; y: number }) {
    this.maxOffsetX = value.x
    this.maxOffsetY = value.y
  }

  /**
   * 获取滚动到视图中的顶部子元素
   */
  get topItem(): number {
    const top = this.bounds.top - this.offsetY
    
    // 使用二分查找找到顶部可见的子元素
    let low = 0
    let high = this.childBounds.length - 1
    
    while (low <= high) {
      const mid = Math.floor((low + high) / 2)
      const bounds = this.childBounds[mid]
      
      if (top < bounds.top) {
        high = mid - 1
      } else if (top > bounds.bottom) {
        low = mid + 1
      } else {
        return mid
      }
    }
    
    return Math.min(low, this.childBounds.length - 1)
  }

  /**
   * 获取当前的边界
   */
  get currentBounds(): Bounds {
    return { ...this.bounds }
  }

  /**
   * 设置当前的边界
   */
  set currentBounds(bounds: Bounds) {
    this.bounds = bounds
  }

  /**
   * 获取指定子元素的边界
   */
  getBoundsForItem(index: number): Bounds | undefined {
    return this.childBounds[index]
  }

  /**
   * 设置子元素的边界
   */
  setChildBounds(bounds: Bounds[]): void {
    this.childBounds = bounds
  }

  /**
   * 滚动到指定的子元素，确保其完全可见
   */
  scrollToItem(index: number): void {
    const bounds = this.childBounds[index]
    if (!bounds) {
      return
    }

    // 垂直滚动
    if (bounds.top + this.offsetY < this.bounds.top) {
      this.offsetY = this.bounds.top - bounds.top
    } else if (bounds.bottom + this.offsetY > this.bounds.bottom) {
      this.offsetY = this.bounds.bottom - bounds.bottom
    }

    // 水平滚动
    if (bounds.left + this.offsetX < this.bounds.left) {
      this.offsetX = this.bounds.left - bounds.left
    } else if (bounds.right + this.offsetX > this.bounds.right) {
      this.offsetX = this.bounds.right - bounds.right
    }
  }

  /**
   * 滚动到底部
   */
  scrollToBottom(): void {
    this.scrollToItem(this.childBounds.length - 1)
  }

  /**
   * 滚动到顶部
   */
  scrollToTop(): void {
    this.scrollToItem(0)
  }

  /**
   * 设置滚动偏移量
   */
  setOffset(x: number, y: number): void {
    this.offsetX = x
    this.offsetY = y
  }

  /**
   * 获取逻辑滚动顶部
   */
  get logicalScrollTop(): { index: number; offset: number } {
    const index = this.topItem
    const bounds = this.childBounds[index]
    
    if (bounds) {
      return {
        index,
        offset: bounds.top + this.offsetY - this.bounds.top
      }
    } else {
      return { index, offset: 0 }
    }
  }

  /**
   * 获取子元素数量
   */
  get childrenCount(): number {
    return this.childBounds.length
  }
}